-- socket功能模块
-- 2021.05.13
-- Lingd
-- 福州泰诚网络科技有限公司

module(..., package.seeall)

require "socket"
require "serptl"
require "config"
require "nvm"
require "hc595"

local socketClient
local SOCKET_CLSOE_NUM = 0
local SOCKET_LINK_NUM  = 0

local ADDR,PORT,c                                   -- 此处的IP和端口请填上你自己的socket服务器和端口

-- 异步接口
sys.taskInit(function()
    -- 初始化参数管理模块
    nvm.init("config.lua")
    -- 从配置文件中获取IP地址和端口号
    ADDR = nvm.get("SerIP")
    PORT = nvm.get("SerPort")
    
    hc595.LED_SYS(2)                                                    -- 刚开机，红灯亮
    hc595.LED_Show(hc595.DEV_4G,hc595.LED_RED,300,300)                  -- 未附网，红灯闪烁
    
    while true do
        while not socket.isReady() do
            sys.wait(1000) 
        end
        hc595.LED_4G(3)                                                 -- 已附网，亮绿色
        hc595.LED_Show(hc595.DEV_TCP,hc595.LED_RED,300,300)             -- 未入网，亮红灯
        --创建一个socket tcp客户端
        socketClient = socket.tcp()
        --阻塞执行socket connect动作，直至成功
        while not socketClient:connect(ADDR, PORT) do 
			SOCKET_LINK_NUM = SOCKET_LINK_NUM+1
            -- 连接失败次数超过，则进行异常处理
            if SOCKET_LINK_NUM > 10 then
                SOCKET_LINK_NUM = 0
                sys.restart('连接失败次数，软件重启')                   -- 连接失败次数，软件重启
            end
			sys.wait(2000) 
		end
        serptl.init()
        while socketClient:asyncSelect(100, "") do end                  -- 空闲超过100秒，则发起，用于保持连接
        socketClient:close()
        hc595.LED_Show(hc595.DEV_TCP,hc595.LED_RED,300,300)             -- 未入网，红灯闪烁
        hc595.LED_SYS(2)                                                -- 掉线了，红灯亮
        SOCKET_CLSOE_NUM = SOCKET_CLSOE_NUM+1
        -- 断开次数超过，则进行异常处理
        if SOCKET_CLSOE_NUM > 10 then
            SOCKET_CLSOE_NUM = 0
            sys.restart('断开次数超过，软件重启')                       -- 请求失败，软件重启
        end
        sys.wait(5000)                                                  -- 断开5秒后重连 
    end
end)

-- 用于异步发送消息
-- 这里用非线程发送数据
function send(str)
    if socket.isReady() then
        socketClient:asyncSend(str)
    end
end

-- 用于异步发送字节流
-- 这里用非线程发送数据
function writeBytes(buff)
    if socket.isReady() then
        socketClient:asyncSend(unpack(buff))
    end
end

-- 异步回调接收数据
sys.subscribe("SOCKET_RECV", function(id)
    if socketClient.id == id then
        local data = socketClient:asyncRecv()
        log.info("这是服务器下发数据:", #data, data)

        -- 转换为table才能进行解析
        local i
        local buf = {}
        for i=1,string.len(data) do
        buf[i] = string.sub(data,i,i) end                -- “123456”字符串分解为‘1’‘2’‘3’‘4’‘5’‘6’    
        serptl.ParsePack(buf,data)
    end
end)